iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0
Mobile Development

Android與Spring Boot開發學習之旅系列 第 18

開發學習之旅 Day18 - 實現登入和註冊功能

  • 分享至 

  • xImage
  •  

使用 Java Spring Boot 透過 Spring Security 和 JSON Web Token 整合,實現身份驗證機制建立安全的登入和註冊系統。

建立Entity類

定義使用者實體類,該類包含使用者的相關資訊。同時實作 Spring Security 的 UserDetails 介面,用於管理和驗證使用者身份。

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "_user")
public class AppUserEntity implements UserDetails {
    @Id
    @GeneratedValue
    private Long id;
    @Column(unique = true) //唯一性約束。
    private String email;
    private String userName;
    private String password;
    @Enumerated(EnumType.STRING) //將枚舉值作為字串存儲
    private AppUserRole userRole;

    public AppUserEntity(String userName, String email, String password, AppUserRole userRole) {
        this.userName = userName;
        this.email = email;
        this.password = password;
        this.userRole = userRole;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return List.of(new SimpleGrantedAuthority(userRole.name()));
    }

    @Override
    public String getUsername() {
        return email;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public boolean isAccountNonExpired() {
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        return false;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return false;
    }

    @Override
    public boolean isEnabled() {
        return false;
    }

}

建立Role類

利用枚舉型別定義角色,用於控制使用者在系統中的權限和許可。

public enum AppUserRole {
    USER,
    ADMIN
}

建立Repository類

使用者 Repository 接口,並使用 Spring Data JPA 來對AppUserEntity進行資料庫操作。

@Repository
public interface AppUserRepository extends JpaRepository<AppUserEntity, Long> {
    Optional<AppUserEntity> findByEmail(String email);
}

建立Service類

用於處理身份驗證相關邏輯,註冊並生成JWT進行登入驗證。

@Service
@Slf4j
@AllArgsConstructor
public class AuthenticationService {

    private final AppUserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final AuthenticationManager authenticationManager;
    private final JwtService jwtService;

    //註冊
    public StatusResponse register(RegisterRequest request){
        var user = AppUserEntity.builder()
                .userName(request.getUserName())
                .password(passwordEncoder.encode(request.getPassword()))
                .email(request.getEmail())
                .userRole(AppUserRole.USER)
                .build();
        userRepository.save(user);
        return StatusResponse.builder()
                .status("註冊成功")
                .build();
    }

    //登入
    public AuthenticationResponse login(LoginRequest request) {
        authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        request.getEmail(),
                        request.getPassword()
                )
        );
        var user = userRepository.findByEmail(request.getEmail()).orElseThrow();
        var jwtToken = jwtService.generateToken(user);
        return AuthenticationResponse.builder()
                .status("登入成功")
                .token(jwtToken)
                .build();
    }
}

建立Controller類

Spring Boot控制器,用於處理與身份驗證相關的 HTTP 請求。

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
@Slf4j
public class AuthenticationController {

    private final AuthenticationService service;

    // 註冊接口
    @PostMapping("/register")
    public ResponseEntity<StatusResponse> register(
            @RequestBody @Validated RegisterRequest request
    ){
        return ResponseEntity.ok(service.register(request));
    }

    // 登入接口
    @PostMapping("/login")
    public ResponseEntity<AuthenticationResponse> login(
            @RequestBody @Validated LoginRequest request
    ) {
        return ResponseEntity.ok(service.login(request));
    }

}

建立Request和Response類

RegisterRequest

定義用於註冊的請求資料結構。

@Data
public class RegisterRequest {
    @NotBlank
    private String userName;

    @NotBlank
    @Email
    private String email;

    @NotBlank
    private String password;

}

LoginRequest

定義用於登入的請求資料結構。

@Data
public class LoginRequest {
    @NotBlank
    @Email
    private String email;
    @NotBlank
    private String password;
}

AuthenticationResponse

定義身份驗證回應的資料結構,包括狀態碼和令牌。

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AuthenticationResponse {
    private String status;
    private String token;
}

上一篇
開發學習之旅 Day17 - Spring Boot三層式架構
下一篇
開發學習之旅 Day19 - 全局異常處理
系列文
Android與Spring Boot開發學習之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言